<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>js无限级下拉列表插件demo</title>
	</head>

	<body>
		<div>
			原生下拉列表实现:<br><br> select1:
			<select id="select1">

			</select>
			</br>
			select2:
			<select id="select2">

			</select>
			</br>
			select3:
			<select id="select3">

			</select>
			</br>
			select4:
			<select id="select4">

			</select>
			</br><br>
			<div id="msg1" style="color: blue;">

			</div>
		</div>

		<script src="js/jquery-1.12.4.js"></script>
		<script src="../SelectCascade.js" type="text/javascript" charset="utf-8"></script>
		<script type="text/javascript">
			(function() {
				var dataArr = []; //缓存获取到的数据
				var selectCascade = null;

				function myRenderSelect(selectId, selectData, selectVal) {
					var html = "";
					html += "<option value=''>请选择</option>";
					if(selectData && selectData.length) {
						for(var i = 0; i < selectData.length; i++) {
							var obj = selectData[i];
							html += "<option value='" + obj.id + "'>" + obj.id + "</option>";
						}
					}
					$("#" + selectId).html(html).val(selectVal);
				}

				/**
				 * 为下拉列表添加触发事件
				 */
				function setAllSelectChangeEvent() {
					var selectIdArr = ["select1", "select2", "select3", "select4"];
					var len = selectIdArr.length,
						selectId;
					for(var i = 0; i < len; i++) {
						selectId = selectIdArr[i];
						changeEvent(selectId, i);
					}

					function changeEvent(selectId, index) {
						$("#" + selectId).on('change', function() {
							var val = $(this).val();
							//渲染当前数据的下级列表
							selectCascade.renderSelectCascade({
								defaultSelectIdArr: [val],
								startLevel: index
							});
						})
					}
				}

				$(function() {
					//1.初始化SelectCascade
					selectCascade = new SelectCascade([{
						getSelectData: function(parentId, callback) {
							searchDataFromServer(parentId, callback);
						},
						renderSelect: function(selectData, selecVal, next) {
							myRenderSelect("select1", selectData, selecVal);
							next && next(); //渲染下一级列表
						}
					}, {
						getSelectData: function(parentId, callback) {
							searchDataFromServer(parentId, callback);
						},
						renderSelect: function(selectData, selecVal, next) {
							myRenderSelect("select2", selectData, selecVal);
							next && next();
						}
					}, {
						getSelectData: function(parentId, callback) {
							searchDataFromServer(parentId, callback);
						},
						renderSelect: function(selectData, selecVal, next) {
							myRenderSelect("select3", selectData, selecVal);
							next && next();
						}
					}, {
						getSelectData: function(parentId, callback) {
							searchDataFromServer(parentId, callback);
						},
						renderSelect: function(selectData, selecVal, next) {
							myRenderSelect("select4", selectData, selecVal);
							if(selectData && selectData.length) {
								$("#select4").show();
							} else {
								$("#select4").hide(); //该列表无数据,隐藏
							}
							next && next();
						}
					}], {
						ROOT: "root",
						renderEnd: function() {
							var start = selectCascade.startTime;
							var end = new Date().getTime();
							$("#msg1").html("列表加载完成 用时t=" + (end - start) + "ms");
						},
						renderStart: function() {
							var start = new Date().getTime();
							selectCascade.startTime = start;
							$("#msg1").html("列表开始加载...");
						}
					});

					//2.设置触发事件
					setAllSelectChangeEvent();

					//3.初始化第一级列表数据
					/*selectCascade.addSelectDataToCache([{
						"id": "1",
						"parentId": "root",
						"selectLevel": 0
					}, {
						"id": "2",
						"parentId": "root",
						"selectLevel": 0
					}, {
						"id": "3",
						"parentId": "root",
						"selectLevel": 0
					}, {
						"id": "4",
						"parentId": "root",
						"selectLevel": 0
					}]);*/

					//4.初始化列表,数据自动从服务器获取
					selectCascade.renderSelectCascade({
						defaultSelectIdArr: ["root", "1", "11", "112", "1122"]
					});
				})

				/**
				 * 模拟从服务器端取数据
				 * @param {String} parentId
				 */
				function searchDataFromServer(parentId, callback) {
					if(dataArr && dataArr.length > 0) {
						setTimeout(function() {
							var i = 0,
								len = dataArr.length;
							var childrenArr = [];
							for(i = 0; i < len; i++) {
								var dataObj = dataArr[i];
								if(dataObj["parentId"] === parentId) {
									childrenArr.push(dataObj);
								}
							}
							if(childrenArr.length === 0) {
								childrenArr = randomCreateData(parentId);
							}
							callback(childrenArr);
						}, 500)
					} else {
						$.getJSON("js/selectData.json", function(data) {
							dataArr = data;
							searchDataFromServer(parentId, callback);
						})
					}
				}

				/**
				 * 随机生成数据
				 * @param {String} parentId
				 */
				function randomCreateData(parentId) {
					var createDataArr = [];
					var dataNum = Math.floor(Math.random() * 9);
					for(var i = 0; i < dataNum; i++) {
						var id = Math.floor(Math.random() * 90000 + 10000);
						createDataArr.push({
							"id": id,
							"parentId": parentId
						})
					}
					return createDataArr;
				}
			})();
		</script>

		<style type="text/css">
			.inline-div {
				display: inline-block;
				vertical-align: top;
			}
			
			.ul_select {
				list-style: none;
				padding: 0;
				margin: 0;
				border: 1px solid lightblue;
				border-left: 0;
				border-bottom: 0;
				width: 100px;
				cursor: pointer;
			}
			
			.ul_select>li {
				list-style: none;
				height: 30px;
				line-height: 30px;
				color: gray;
				padding: 0;
				text-align: center;
				border-bottom: 1px solid lightblue;
				border-left: 4px solid lightgrey;
			}
			
			.ul_select .sel {
				color: orange;
				border-left: 4px solid orange;
			}
		</style>
		<div>
			<br>自定义下拉列表实现:<br>
			<div style="margin-top: 10px;margin-bottom: 10px;">
				<div class="inline-div">
					ul_select1:
					<ul id="ul_select1" class="ul_select">
						<li></li>
					</ul>
				</div>
				<div class="inline-div">
					ul_select2:
					<ul id="ul_select2" class="ul_select">
						<li></li>
					</ul>
				</div>
				<div class="inline-div">
					ul_select3:
					<ul id="ul_select3" class="ul_select">
						<li></li>
					</ul>
				</div>
				<div class="inline-div">
					ul_select4:
					<ul id="ul_select4" class="ul_select">
						<li></li>
					</ul>
				</div>
			</div>

			<div id="msg2" style="color: blue;">

			</div>
		</div>

		<script type="text/javascript">
			(function() {
				var dataArr = []; //缓存获取到的数据
				var selectCascade = null;
				var selectIdArr = ["ul_select1", "ul_select2", "ul_select3", "ul_select4"];

				function myRenderSelect(selectId, selectData, selectVal, next) {
					var $select = $("#" + selectId);

					var html = "";
					html += "<li data-value=''>不限</li>";
					if(!next) {
						$select.html(html);
						return;
					}

					$select.hide();
					if(selectData && selectData.length) {
						for(var i = 0; i < selectData.length; i++) {
							var obj = selectData[i];
							html += "<li data-value='" + obj.id + "'>" + obj.id + "</li>";
						}
					}
					$select.html(html);
					selSelectItem(selectId, selectVal);
					$select.fadeIn(500, function() {
						next();
					});
				}

				function selSelectItem(selectId, selectVal) {
					$("#" + selectId).children("li").each(function() {
						var itemVal = $(this).attr("data-value");
						$(this).removeClass("sel");
						if(itemVal == selectVal) {
							$(this).addClass("sel");
						}
					})
				}

				/**
				 * 为下拉列表添加触发事件
				 */
				function setAllSelectClickEvent() {
					var len = selectIdArr.length,
						selectId;
					for(var i = 0; i < len; i++) {
						selectId = selectIdArr[i];
						clickEvent(selectId, i);
					}

					function clickEvent(selectId, index) {
						$("#" + selectId).on('click', function() {
							var e = e || window.event;
							var target = e.target || e.srcElement;
							//判断事件目标是否是li
							if(target.tagName.toLowerCase() != "li") {
								return;
							}
							var val = $(target).attr("data-value");
							if(val == null) {
								return;
							}
							selSelectItem(selectId, val);

							//渲染当前数据的下级列表
							selectCascade.renderSelectCascade({
								defaultSelectIdArr: [val],
								startLevel: index
							});
						})
					}
				}

				$(function() {
					var selectConfigArr = (function() {
						var len = selectIdArr.length,
							selectId;
						var selectConfigArr = [];
						for(var i = 0; i < len; i++) {
							selectId = selectIdArr[i];
							initSelectConfig(selectId);
						}

						function initSelectConfig(selectId) {
							selectConfigArr.push({
								getSelectData: function(parentId, callback) {
									searchDataFromServer(parentId, callback);
								},
								renderSelect: function(selectData, selecVal, next) {
									myRenderSelect(selectId, selectData, selecVal, next);
								}
							});
						}

						return selectConfigArr;
					})();

					//1.初始化SelectCascade
					selectCascade = new SelectCascade(selectConfigArr, {
						ROOT: "root",
						renderEnd: function() {
							var start = selectCascade.startTime;
							var end = new Date().getTime();
							$("#msg2").html("列表加载完成 用时t=" + (end - start) + "ms");
						},
						renderStart: function() {
							var start = new Date().getTime();
							selectCascade.startTime = start;
							$("#msg2").html("列表开始加载...");
						}
					});

					//2.设置触发事件
					setAllSelectClickEvent();

					//3.初始化列表,数据自动从服务器获取
					selectCascade.renderSelectCascade({
						defaultSelectIdArr: ["root"]
					});
				})

				/**
				 * 模拟从服务器端取数据
				 * @param {String} parentId
				 */
				function searchDataFromServer(parentId, callback) {
					setTimeout(function() {
						var childrenArr = randomCreateData(parentId);
						callback(childrenArr);
					}, 5)
				}

				/**
				 * 随机生成数据
				 * @param {String} parentId
				 */
				function randomCreateData(parentId) {
					var createDataArr = [];
					var dataNum = Math.floor(Math.random() * 4 + 3);
					for(var i = 0; i < dataNum; i++) {
						var id = Math.floor(Math.random() * 900000 + 100000);
						createDataArr.push({
							"id": id,
							"parentId": parentId
						})
					}
					return createDataArr;
				}
			})();
		</script>
	</body>

</html>